﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace OCESandbox
{
    [Serializable]
    public sealed class ProxyDomain : MarshalByRefObject
    {
        private OpenFileDialog openFileDialog = null;

        public ProxyDomain()
        {
            AppDomain current = AppDomain.CurrentDomain;
            string domain = AppDomain.CurrentDomain.FriendlyName;
        }

        public Assembly GetAssembly(string path)
        {
            try
            {
                return Assembly.LoadFrom(path);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(ex.Message);
            }
        }
        public ClassInformation[] LoadAssemblyInMyDomain(string path)
        {
            if(File.Exists(path))
            {
                byte[] assemblyBytes = File.ReadAllBytes(path);
                AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve;
                Assembly assembly = AppDomain.CurrentDomain.Load(assemblyBytes);
                var entities = new List<Type>(assembly.GetTypes());
                var result = new List<ClassInformation>();
                foreach (var entity in entities)
                {
                    if(entity.BaseType != null && entity.BaseType.FullName == "System.ServiceModel.DomainServices.Client.Entity")
                    {
                        result.Add(new ClassInformation()
                                       {
                                           Name = entity.Name,
                                           Namespace = entity.Namespace
                                       });
                    }
                }
                return result.ToArray();
            }
            return null;
        }

        Assembly CurrentDomainAssemblyResolve(object sender, ResolveEventArgs args)
        {
            string slpath =Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
            string assemblyfileName = new AssemblyName(args.Name).Name + ".dll";
            string path = string.Format(@"{0}\Reference Assemblies\Microsoft\Framework\Silverlight\v5.0\{1}", slpath, assemblyfileName);
            if(File.Exists(path))
            {
                Assembly assembly= Assembly.LoadFrom(path);
                AppDomain.CurrentDomain.Load(assembly.GetName());
                return assembly;
            }
            if(openFileDialog==null)
                openFileDialog=new OpenFileDialog();
            openFileDialog.FileName = assemblyfileName;
            openFileDialog.Title = string.Format("Looking for({0})", assemblyfileName);
            openFileDialog.Filter = "Library files (*.dll)|*.dll";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                Assembly assembly = Assembly.LoadFrom(openFileDialog.FileName);
                AppDomain.CurrentDomain.Load(assembly.GetName());
                return assembly;
            }
            else
                return null;
        }
     
        public string Ping()
        {
            return "Hello";
        }
     
    }
}
